﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace ComicsEditor
{
    public class Page
    {
        public readonly int Width;
        public readonly int Height;

        public RectangleF Output;

        public List<PageObject> Objects = new List<PageObject>();

        public Instrument Instrument = null;
        public bool InstrumentOverride = false;

        public PageObject MoveObject = null;
        public PageObject ActiveObject = null;
        private Point offsetActivate;
        private Point pointActivate;
        private Point pointMove;

        public bool Changed = false;

        public Page(int Width, int Height)
        {
            this.Width = Width;
            this.Height = Height;
        }

        public void Add(PageObject obj)
        {
            int i;
            for (i = Objects.Count; i > 0 && Objects[i - 1].Order > obj.Order; i--);
            Objects.Insert(i, obj);
            Changed = true;
        }

        public void Remove(PageObject obj)
        {
            Objects.Remove(obj);
            Changed = true;
        }

        public PointF Transform(Point point)
        {
            return new PointF(Output.X + point.X*Output.Width/Width, Output.Y + point.Y*Output.Height/Height);
        }

        public SizeF Transform(Size size)
        {
            return new SizeF(size.Width*Output.Width/Width, size.Height*Output.Height/Height);
        }

        public Point Transform(PointF point)
        {
            return new Point((int)((point.X - Output.X)/Output.Width*Width), (int)((point.Y - Output.Y)/Output.Height*Height));
        }

        public Size Transform(SizeF size)
        {
            return new Size((int)(size.Width/Output.Width*Width), (int)(size.Height/Output.Height*Height));
        }

        public Matrix GetTransform(Point point)
        {
            PointF pointF = Transform(point);
            return new Matrix(Output.Width/Width, 0, 0, Output.Height/Height, pointF.X, pointF.Y);
        }

        public void Draw(Graphics Graphics)
        {
            for (int i = 0; i < Objects.Count; i++)
                if (Objects[i].Visible)
                    Objects[i].Draw(Graphics);
            Changed = false;
        }

        public bool OnMouseDown(PointF point)
        {
            Point local = Transform(point);
            if (local.X < 0 || local.X >= Width || local.Y < 0 || local.Y >= Height)
                return false;
            if (!InstrumentOverride)
                for (int i = 0; i < Objects.Count; i++)
                    if (Objects[i].Visible && Objects[i].Activate(local, out offsetActivate))
                    {
                        ActiveObject = Objects[i];
                        pointActivate = local;
                        pointMove = local;
                        return true;
                    }
            if (Instrument != null && Instrument.Activate(local, out offsetActivate))
            {
                ActiveObject = Instrument;
                pointActivate = local;
                pointMove = local;
                return true;
            }
            return false;
        }

        public void OnMouseMove(PointF point)
        {
            Point local = Transform(point);
            if (MoveObject != null)
            {
                MoveObject.Move(local, new Point(local.X - pointMove.X, local.Y - pointMove.Y));
            }
            if (ActiveObject != null)
            {
                ActiveObject.Drag(local, offsetActivate, new Point(local.X - pointActivate.X, local.Y - pointActivate.Y), new Point(local.X - pointMove.X, local.Y - pointMove.Y));
            }
            pointMove = local;
        }

        public void OnMouseUp()
        {
            if (ActiveObject != null)
            {
                ActiveObject.Deactivate();
                ActiveObject = null;
            }
        }
    }
}
